﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
		<title>EntityFramework Integration</title>
		<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
		<style type="text/css">
.auto-style2 {
	font-weight: normal;
}
		</style>
	</head>

	<body>

		<div class="document-contents">

			<p>ASP.NET Boilerplate can work with any O/RM framework. It has built-in 
integration with <b>EntityFramework</b>. This document will explain how to 
use EntityFramework with ASP.NET Boilerplate. It's assumed that you're already familar with 
EntityFramework in a 
basic level.</p>
			<h3 id="DocNugetPackage">Nuget Package</h3>
			<p>Nuget package to use EntityFramework as O/RM in ASP.NET Boilerplate is
				<a href="http://www.nuget.org/packages/Abp.EntityFramework" target="_blank">Abp.EntityFramework</a>. You should add it to your application. It's 
better to implement EntityFramework in a seperated assembly (dll) in your application 
and depend on that package from this assembly.</p>
			<h3 id="DocDbContext">DbContext</h3>
			<p>As you know, to work with EntityFramework, you should define a <strong>DbContext</strong> 
class for your application. An example DbContext is shown below:</p>
			<pre lang="cs">public class SimpleTaskSystemDbContext : AbpDbContext
{
    public virtual IDbSet&lt;Person&gt; People { get; set; }
    public virtual IDbSet&lt;Task&gt; Tasks { get; set; }

    public SimpleTaskSystemDbContext()
        : base("Default")
    {

    }
    
    public SimpleTaskSystemDbContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {

    }

    public SimpleTaskSystemDbContext(DbConnection existingConnection)
        : base(existingConnection, false)
    {

    }

    public SimpleTaskSystemDbContext(DbConnection existingConnection, bool contextOwnsConnection)
        : base(existingConnection, contextOwnsConnection)
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity&lt;Person&gt;().ToTable("StsPeople");
        modelBuilder.Entity&lt;Task&gt;().ToTable("StsTasks").HasOptional(t =&gt; t.AssignedPerson);
    }
}</pre>
			<p>It's a regular DbContext class except following rules:</p>
			<ul>
				<li>It's derived from <strong>AbpDbContext</strong> instead of 
				DbContext.</li>
				<li>It should have constructors as the sample above (constructor 
				parameter names should also be same). Explanation:<ul>
					<li><strong>Default</strong> consturctor passes "Default" to 
					base bass as the connection string. So, it expects a 
					"Default" named connection string in the 
					web.config/app.config file. This constructor is not used by 
					ABP, but used by EF command line migration tool commands 
					(like update-database).</li>
					<li>The constructor gets <strong>nameOrConnectionString</strong> 
					is used by ABP to pass the connection name or string on 
					runtime.</li>
					<li>The constructor get <strong>existingConnection</strong> 
					can be used for unit test and not directly used by ABP.</li>
					<li>The constructor gets <strong>existingConnection </strong>
					and <strong>contextOwnsConnection </strong>is used by ABP on 
					single database multiple dbcontext scenarios to share same 
					connection &amp; transaction () when <strong>DbContextEfTransactionStrategy</strong> 
					is used (see Transaction Management section below).</li>
				</ul>
				</li>
			</ul>
			<p>EntityFramework can map classes to database tables in a 
conventional way. You even don't need to make any configuration unless you make 
some custom stuff. In this example, we mapped entities to different tables. As 
default, Task entity maps to <strong>Tasks</strong> table. But we changed it to 
be <strong>StsTasks</strong> table. Instead of configuring it with data 
annotation attributes, I prefered to use fluent configuration. You can choice 
the way you like.</p>

			<h3 id="DocRepositories">Repositories</h3>
			<p>Repositories are used to abstract data access from higher layers. 
			See <a href="Repositories.html">repository documentation</a> for 
			more.&nbsp;</p>
			<h4 id="DocImplRepositories">Default Repositories</h4>
			<p>
				<a href="http://www.nuget.org/packages/Abp.EntityFramework" target="_blank">Abp.EntityFramework</a> 
			implements default repositories for all entities defined in your 
			DbContext. You don't have to create repository classes to use 
predefined repository methods. Example:</p>
			<pre lang="cs">public class PersonAppService : IPersonAppService
{
    private readonly <strong>IRepository&lt;Person&gt; _personRepository</strong>;

    public PersonAppService(<strong>IRepository&lt;Person&gt; personRepository</strong>)
    {
        _personRepository = personRepository;
    }

    public void CreatePerson(CreatePersonInput input)
    {        
        person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };

        <strong>_personRepository.Insert(person);
</strong>    }
}</pre>

			<p>PersonAppService contructor-injects <strong>IRepository&lt;Person&gt;</strong> and 
uses the <strong>Insert</strong> method. In this way, you can easily inject
				<strong>IRepository&lt;TEntity&gt;</strong> (or 
			IRepository&lt;TEntity, TPrimaryKey&gt;) and use predefined methods.</p>

			<h4 id="DocCustomRepositoryMethods">Custom Repositories</h4>
			<p>If standard repository methods are not sufficient, you can create 
			custom repository classes for your entities.</p>
			<h5 id="DocAppBaseRepo">Application Specific Base Repository Class</h5>

			<p>ASP.NET Boilerplate provides a base class <strong>EfRepositoryBase</strong> 
to implement repositories easily. To implement <strong>IRepository</strong> interface, you can 
just derive your repository from this class. But it's better to create your own 
base class that extens EfRepositoryBase. Thus, you can add shared/common methods 
to your repositories or override existing methods easily. An example base class all for repositories of a <em>SimpleTaskSystem</em> application:</p>
			<pre lang="cs">//Base class for all repositories in my application
public class SimpleTaskSystemRepositoryBase&lt;TEntity, TPrimaryKey&gt; : <strong>EfRepositoryBase&lt;SimpleTaskSystemDbContext, TEntity, TPrimaryKey&gt;</strong>
    where TEntity : class, IEntity&lt;TPrimaryKey&gt;
{
    public SimpleTaskSystemRepositoryBase(<strong>IDbContextProvider&lt;SimpleTaskSystemDbContext&gt; dbContextProvider</strong>)
        : base(dbContextProvider)
    {
    }

    //add common methods for all repositories
}

//A shortcut for entities those have integer Id
public class SimpleTaskSystemRepositoryBase&lt;TEntity&gt; : <strong>SimpleTaskSystemRepositoryBase&lt;TEntity, int&gt;</strong>
    where TEntity : class, IEntity&lt;int&gt;
{
    public SimpleTaskSystemRepositoryBase(<strong>IDbContextProvider&lt;SimpleTaskSystemDbContext&gt; dbContextProvider</strong>)
        : base(dbContextProvider)
    {
    }

    //do not add any method here, add to the class above (because this class inherits it)
}</pre>
			<p>Notice that we're inheriting from EfRepositoryBase&lt;<strong>SimpleTaskSystemDbContext</strong>, TEntity, TPrimaryKey&gt;. 
This declares to ASP.NET Boilerplate to use SimpleTaskSystemDbContext in our 
repositories.</p>
			<p>By default, all repositories for your given DbContext 
			(SimpleTaskSystemDbContext in this example) is implemented using 
			EfRepositoryBase. You can replace it to your own repository base 
			repository class by adding <strong>AutoRepositoryTypes</strong> 
			attribute to your DbContext as shown below:</p>
<pre lang="cs"><strong>[AutoRepositoryTypes(
    typeof(IRepository&lt;&gt;),
    typeof(IRepository&lt;,&gt;),
    typeof(SimpleTaskSystemEfRepositoryBase&lt;&gt;),
    typeof(SimpleTaskSystemEfRepositoryBase&lt;,&gt;)
)]</strong>
public class SimpleTaskSystemDbContext : AbpDbContext
{
    ...
}</pre>
			<h5>Custom Repository Example</h5>

			<p>To implement a custom repository, just derive from your application specific 
base repository class we created above.</p>
			<p>Assume that we have a Task entity that can be assigned to a Person (entity) 
and a Task has a State (new, assigned, completed... and so on). We may need to 
write a custom method to get list of Tasks with some conditions and with 
AssisgnedPerson property pre-fetched (included) in a single database query. See the example 
code:</p>
			<pre>public interface ITaskRepository : <strong>IRepository&lt;Task, long&gt;
</strong>{
    List&lt;Task&gt; GetAllWithPeople(int? assignedPersonId, TaskState? state);
}

public class TaskRepository : <strong>SimpleTaskSystemRepositoryBase&lt;Task, long&gt;, ITaskRepository
</strong>{
    public TaskRepository(IDbContextProvider&lt;SimpleTaskSystemDbContext&gt; dbContextProvider)
        : base(dbContextProvider)
    {
    }

    public List&lt;Task&gt; GetAllWithPeople(int? assignedPersonId, TaskState? state)
    {
        var query = GetAll();

        if (assignedPersonId.HasValue)
        {
            query = query.Where(task =&gt; task.AssignedPerson.Id == assignedPersonId.Value);
        }

        if (state.HasValue)
        {
            query = query.Where(task =&gt; task.State == state);
        }

        return query
            .OrderByDescending(task =&gt; task.CreationTime)
            .Include(task =&gt; task.AssignedPerson)
            .ToList();
    }
}</pre>
			<p>
				<strong class="auto-style2">We first defined </strong>ITaskRepository and 
then implemented it.<strong> GetAll()</strong> returns <strong>IQueryable&lt;Task&gt;</strong>, then we can add some
				<strong>Where</strong> filters using given parameters. Finally we can call
				<strong>ToList()</strong> to get list of 
Tasks.</p>
			<p>You can also use <strong>Context </strong>object in repository methods to 
reach to your DbContext and directly use Entity Framework APIs.&nbsp;</p>
			<p><strong>Note</strong>: Define the custom repository <strong>
			interface </strong>in the <strong>domain/core</strong> layer,
			<strong>implement </strong>it in the <strong>EntityFramework
			</strong>project for layered applications. Thus, you can inject the 
			interface from any project without referencing to EF.</p>
			<h4>Repository Best Practices</h4>
			<ul>
				<li><strong>Use default repositories</strong> wherever it's 
				possible. You can use default repository even you have a custom 
				repository for an entity (if you will use standard repository 
				methods).</li>
				<li>Always create <strong>repository base class</strong> for 
				your application for custom repositories, as defined above.</li>
				<li>Define <strong>interfaces </strong>for your custom 
				repositories in <strong>domain layer</strong> (.Core project in 
				startup template), custom repository <strong>classes </strong>in
				<strong>.EntityFramework</strong> project if you want to 
				abstract EF from your domain/application.</li>
			</ul>
			<h3>Transaction Management</h3>
			<p>ASP.NET Boilerplate has a built-in <a href="Unit-Of-Work.html">
			unit of work</a> system to manage database connection and 
			transactions. Entity framework has different
			<a href="https://msdn.microsoft.com/en-us/library/dn456843(v=vs.113).aspx" target="_blank">
			transaction management approaches</a>. ASP.NET Boilerplate uses 
			ambient TransactionScope approach by default, but also has a 
			built-in implementation for DbContext transaction API. If you want 
			to switch to DbContext transaction API, you can configure it in 
			PreInitialize method of your <a href="Module-System.html">module</a> 
			like that:</p>
			<pre lang="cs">Configuration.ReplaceService&lt;IEfTransactionStrategy, <strong>DbContextEfTransactionStrategy</strong>&gt;(DependencyLifeStyle.Transient);</pre>
			<p>Remember to add "<em>using Abp.Configuration.Startup;</em>" to 
			your code file to be able to use ReplaceService generic extension 
			method.</p>
			<p>In addition, your DbContext <strong>should have constructors</strong> 
			as described in DbContext section of this document.</p>
			
			<h3>Data Stores</h3>
			<p>Since ASP.NET Boilerplate has built-in integration with EntityFramework, it can work with data stores EntityFramework supports. Our free startup templates are designed to work with Sql Server but you can modify them to work with a different data store.</p>
			<p>For example, if you want to work with MySql, please refer to <a href="EF-MySql-Integration.html">this document </a></p>
		</div>
	</body>

</html>
